package network

import (
	"encoding/binary"
	"errors"

	"github.com/xxtea/xxtea-go/xxtea"
)

const (
	MSG_TAG   = 0x6279
	XXTEA_KEY = "6279baiyikejitest"
)

const (
	ENCRYPT_NON   = 0
	ENCRYPT_XXTEA = 1 << 0
)

const (
	InvliadPacketMainID = uint16(0xFFFF)
)

// 普通封包
type Packet struct {
	MainId uint16 //主命令ID
	SubId  uint16 //子命令ID
	Data   []byte //数据
}

func EncryptByXxtea(data []byte) []byte {
	return xxtea.Encrypt(data, []byte(XXTEA_KEY))
}

func DecryptByXxtea(data []byte) []byte {
	return xxtea.Decrypt(data, []byte(XXTEA_KEY))
}

func (self *Packet) ToByteArray() []byte {
	buffer := make([]byte, PacketCommandSize)
	binary.LittleEndian.PutUint16(buffer[0:2], self.MainId)
	binary.LittleEndian.PutUint16(buffer[2:4], self.SubId)
	buffer = append(buffer[0:PacketCommandSize], self.Data...)
	return buffer
}

func (self *Packet) ToEncryptByteArray() ([]byte, uint8) {
	buffer := make([]byte, PacketCommandSize)

	binary.LittleEndian.PutUint16(buffer[0:2], self.MainId)
	binary.LittleEndian.PutUint16(buffer[2:4], self.SubId)

	buffer = append(buffer[0:PacketCommandSize], self.Data...)
	msgType := uint8(ENCRYPT_XXTEA)

	//加密
	//xxtea
	encryptData := EncryptByXxtea(buffer)
	return encryptData, msgType
}

func ToDecryptPacket(data []byte, msgType uint8) (p *Packet, err error) {

	var decryptData []byte

	//xxtea
	if msgType&uint8(ENCRYPT_XXTEA) != 0 {
		decryptData = DecryptByXxtea(data)
	} else if msgType == ENCRYPT_NON {
		decryptData = data
	} else {
		return nil, errors.New("Error encryption protocol!")
	}

	if len(decryptData) < 4 {
		return nil, errors.New("Packet length is too short")
	}

	p = &Packet{}
	p.MainId = uint16(binary.LittleEndian.Uint16(decryptData[0:2]))
	p.SubId = uint16(binary.LittleEndian.Uint16(decryptData[2:4]))
	p.Data = decryptData[4:]

	return p, nil
}

func MakePacket(mainId uint16, subId uint16, data []byte) *Packet {
	return &Packet{
		MainId: mainId,
		SubId:  subId,
		Data:   data,
	}
}
